﻿/**
 * Copyright(c) Live2D Inc. All rights reserved.
 *
 * Use of this source code is governed by the Live2D Open Software license
 * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
 */

#pragma once

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <Math/CubismMatrix44.hpp>
#include <Math/CubismViewMatrix.hpp>
#include "CubismFramework.hpp"
#include <Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.hpp>

class Live2dModel;

/**
* @brief 描画クラス
*/
class Live2dView
{
public:

    /**
     * @brief LAppModelのレンダリング先
     */
    enum SelectTarget
    {
        SelectTarget_None,                ///< デフォルトのフレームバッファにレンダリング
        SelectTarget_ModelFrameBuffer,    ///< LAppModelが各自持つフレームバッファにレンダリング
        SelectTarget_ViewFrameBuffer,     ///< LAppViewの持つフレームバッファにレンダリング
    };

    /**
    * @brief コンストラクタ
    */
    Live2dView();

    /**
    * @brief デストラクタ
    */
    ~Live2dView();

    /**
    * @brief 初期化する。
    */
    void Initialize();

    /**
    * @brief 描画する。
    */
    void Render();

    void StartMotion(const char*group,const int id);

    void SetExpression(const char* expression);

    void SetExpressionById(const int id);

    void SetSpeed(const float speed);

    void SetRandomMotion(const bool random, const bool randomExpression);

    /************************mouse & keyboard*****************************/
    /**
    * @brief タッチしているときにポインタが動いたら呼ばれる。
    *
    * @param[in]       pointX            スクリーンX座標
    * @param[in]       pointY            スクリーンY座標
    */
    void OnMouseMoved(float pointX, float pointY) const;

    void OnMouseClick(int key, bool key_up) const;

    void OnLeftHandDown(bool key_up) const;

    void OnRightHandDown(bool key_up) const;

    /************************joystick*****************************/

    void OnStickLeftDown(bool key_up)const;

    void OnStickRightDown(bool key_up)const;

    void OnStickShowLeftHand(bool key_up)const;

    void OnStickShowRightHand(bool key_up)const;

    void OnStickL(float x, float y)const;

    void OnStickR(float x, float y)const;

    /*************************************************************/

    /**
    * @brief 伸缩视觉矩阵。
    */
    bool ScaleView(float s_x, float s_y) const;

    /**
   * @brief 移动视觉矩阵。
   */
    bool TranslateView(float t_x, float t_y) const;

    /**
    * @brief X座標をView座標に変換する。
    *
    * @param[in]       deviceX            デバイスX座標
    */
    float TransformViewX(float deviceX) const;

    /**
    * @brief Y座標をView座標に変換する。
    *
    * @param[in]       deviceY            デバイスY座標
    */
    float TransformViewY(float deviceY) const;

    /**
    * @brief X座標をScreen座標に変換する。
    *
    * @param[in]       deviceX            デバイスX座標
    */
    float TransformScreenX(float deviceX) const;

    /**
    * @brief Y座標をScreen座標に変換する。
    *
    * @param[in]       deviceY            デバイスY座標
    */
    float TransformScreenY(float deviceY) const;

    /**
     * @brief   モデル1体を描画する直前にコールされる
     */
    void PreModelDraw(Live2dModel& refModel);

    /**
     * @brief   モデル1体を描画した直後にコールされる
     */
    void PostModelDraw(Live2dModel& refModel);

    /**
     * @brief レンダリング先を切り替える
     */
    void SwitchRenderingTarget(SelectTarget targetType);

    /**
     * @brief レンダリング先をデフォルト以外に切り替えた際の背景クリア色設定
     * @param[in]   r   赤(0.0~1.0)
     * @param[in]   g   緑(0.0~1.0)
     * @param[in]   b   青(0.0~1.0)
     */
    void SetRenderTargetClearColor(float r, float g, float b);

    Csm::CubismMatrix44* GetViewMatrix() { return _viewMatrix; }

    void SetRenderBufferTarget(GLuint id, uint32_t displayBufferWidth, uint32_t displayBufferHeight);

private:
    Csm::CubismMatrix44* _deviceToScreen;    ///< デバイスからスクリーンへの行列
    Csm::CubismViewMatrix* _viewMatrix;      ///< viewMatrix
    GLuint _programId;                       ///< シェーダID

    Csm::Rendering::CubismOffscreenFrame_OpenGLES2 _renderBuffer;   ///< モードによってはCubismモデル結果をこっちにレンダリング
    SelectTarget _renderTarget;     ///< レンダリング先の選択肢
    float _clearColor[4];           ///< レンダリングターゲットのクリアカラー
};
